package ar.edu.uba.fi.jmit.aspecter.parser;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.SAXException;

import ar.edu.uba.fi.jmit.aspecter.core.Constants;
import ar.edu.uba.fi.jmit.aspecter.core.WeavingInstrumentor;
import ar.edu.uba.fi.jmit.aspecter.core.WeavingInstrumentorImpl;
import ar.edu.uba.fi.jmit.aspecter.monitor.invocationCounter.MethodInvocationCounterInstrumentor;
import ar.edu.uba.fi.jmit.aspecter.monitor.methodTime.MethodTimeInstrumentor;
import ar.edu.uba.fi.jmit.aspecter.monitor.objectCount.ObjectCountInstrumentor;
import ar.edu.uba.fi.jmit.aspecter.parser.XMLAspecterParser;
import ar.edu.uba.fi.jmit.aspecter.parser.exception.XMLParserRuntimeException;
import junit.framework.TestCase;

/**
 * Test del parser XML, se testea un archivo por cada tipo de monitoreo.
 * 
 * @author Cristian
 *
 */
public class XMLParserTestCase extends TestCase {
	
	private static String pathToFieldValue = "src/test/resources/testParser/FieldValue.jmit.xml";
	private static String pathToInvocationCounter = "src/test/resources/testParser/InvocationCounter.jmit.xml";
	private static String pathToMethodTime = "src/test/resources/testParser/MethodTime.jmit.xml";
	private static String pathToObjectCounter = "src/test/resources/testParser/ObjectCounter.jmit.xml";
	private static String pathToEnviromentProduction = "src/test/resources/testParser/EnviromentProduction.jmit.xml";
	private static String pathToEnviromentTesting = "src/test/resources/testParser/EnviromentTesting.jmit.xml";
	private static String pathToEnviromentDevelopment = "src/test/resources/testParser/EnviromentDevelopment.jmit.xml";
	private static String pathToFieldValueWithoutClass = "src/test/resources/testParser/FieldValueWithoutClass.jmit.xml";
	private static String pathToInvocationCounterWithNothing = "src/test/resources/testParser/InvocationCounterWithNothing.jmit.xml";
	private static String pathToMethodTimeWithNothing = "src/test/resources/testParser/MethodTimeWithNothing.jmit.xml";
	private static String pathToObjectCounterWithoutClass = "src/test/resources/testParser/ObjectCounterWithoutClass.jmit.xml";
	
	
	public void testParseFieldValue(){
		List<WeavingInstrumentor> instrumentors = new ArrayList<WeavingInstrumentor>();
		try {
			instrumentors = XMLAspecterParser.parse(pathToFieldValue, Constants.ENVIROMENT_DEVELOPMENT);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		assertTrue(instrumentors.get(0) instanceof WeavingInstrumentorImpl);
	}
	
	public void testParseInvocationCounter(){
		List<WeavingInstrumentor> instrumentors = new ArrayList<WeavingInstrumentor>();
		try {
			instrumentors = XMLAspecterParser.parse(pathToInvocationCounter, Constants.ENVIROMENT_DEVELOPMENT);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		assertTrue(instrumentors.get(0) instanceof MethodInvocationCounterInstrumentor);
	}
	
	public void testParseMethodTime(){
		List<WeavingInstrumentor> instrumentors = new ArrayList<WeavingInstrumentor>();
		try {
			instrumentors = XMLAspecterParser.parse(pathToMethodTime, Constants.ENVIROMENT_DEVELOPMENT);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		assertTrue(instrumentors.get(0) instanceof MethodTimeInstrumentor);
	}
	
	public void testParseObjectCount(){
		List<WeavingInstrumentor> instrumentors = new ArrayList<WeavingInstrumentor>();
		try {
			instrumentors = XMLAspecterParser.parse(pathToObjectCounter, Constants.ENVIROMENT_DEVELOPMENT);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		assertTrue(instrumentors.get(0) instanceof ObjectCountInstrumentor);
	}
	
	public void testEnviromentTesting(){
		List<WeavingInstrumentor> instrumentors = new ArrayList<WeavingInstrumentor>();
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentTesting, Constants.ENVIROMENT_DEVELOPMENT);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentTesting, Constants.ENVIROMENT_TESTING);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentTesting, Constants.ENVIROMENT_PRODUCTION);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(0, instrumentors.size());
		
	}
	
	public void testEnviromentProduction(){
		List<WeavingInstrumentor> instrumentors = new ArrayList<WeavingInstrumentor>();
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentProduction, Constants.ENVIROMENT_DEVELOPMENT);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentProduction , Constants.ENVIROMENT_TESTING);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentProduction, Constants.ENVIROMENT_PRODUCTION);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		
	}
	
	public void testEnviromentDevelopment(){
		List<WeavingInstrumentor> instrumentors = new ArrayList<WeavingInstrumentor>();
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentDevelopment, Constants.ENVIROMENT_DEVELOPMENT);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(1, instrumentors.size());
		
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentDevelopment, Constants.ENVIROMENT_TESTING);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(0, instrumentors.size());
		
		try {
			instrumentors = XMLAspecterParser.parse(pathToEnviromentDevelopment, Constants.ENVIROMENT_PRODUCTION);
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			e.printStackTrace();
			fail("XMLParserRuntimeException: " + e.getMessage());
		}
		assertEquals(0, instrumentors.size());
		
	}
	
	public void testFails(){
		try {
			XMLAspecterParser.parse(pathToFieldValueWithoutClass, Constants.ENVIROMENT_DEVELOPMENT);
			fail();
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			//Esta bien
		}
		
		try {
			XMLAspecterParser.parse(pathToInvocationCounterWithNothing, Constants.ENVIROMENT_DEVELOPMENT);
			fail();
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			//Esta bien
		}
		
		try {
			XMLAspecterParser.parse(pathToMethodTimeWithNothing, Constants.ENVIROMENT_DEVELOPMENT);
			fail();
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			//Esta bien
		}
		
		try {
			XMLAspecterParser.parse(pathToObjectCounterWithoutClass, Constants.ENVIROMENT_DEVELOPMENT);
			fail();
		} catch (SAXException e) {
			e.printStackTrace();
			fail("SAXException: " + e.getMessage());
		} catch (IOException e) {
			e.printStackTrace();
			fail("IOException: " + e.getMessage());
		} catch (XMLParserRuntimeException e){
			//Esta bien
		}
		
	}
}
